package csm.common;

/**
 * <b>진법</b>에 관련된 표현과 값의 변환을 처리하는 클래스입니다.
 *
 * @author seungmun
 * @since 2006.1.18.
 *
 */
public final class RadixUtil
{
	/** 진법체계중 기수의 최소값 상수 (2진법) */
	public static final int MIN_RADIX = 2;
	/** 진법체계중 기수의 최대값 상수 (36진법) */
	public static final int MAX_RADIX = 36;

	private static final String digits = "0123456789abcdefghijklmnopqrstuvwxyz";

	/**
	 * 지정한 숫자값(i)을 radix진법의 표현식문자열(접두어가 제외된 ex:0x, 0,...)로 반환합니다.
	 *
	 * @param i
	 *            표현식으로 표현할 대상이 되는 숫자값
	 * @param radix
	 *            표현식으로 표현할 진법
	 * @return 표현식문자열(접두어가 제외된 ex:0x, 0,...)
	 */
	public static String getString(long i, int radix)
	{
		if (radix < MIN_RADIX || radix > MAX_RADIX) radix = 10;

		char[] buf = new char[65];
		int charPos = 64;
		boolean negative = (i < 0);

		if (!negative) i = -i;

		while (i <= -radix)
		{
			buf[charPos--] = digits.charAt((int) (-(i % radix)));
			i = i / radix;
		}

		buf[charPos] = digits.charAt((int) (-i));

		if (negative) buf[--charPos] = '-';

		return String.valueOf(buf, charPos, (65 - charPos));
	}

	/**
	 * 특정 진법의 표현식으로 표현된 내용을 정수값으로 반환합니다. s가 radix진법으로 표현된 표현식입니다.
	 *
	 * @param s
	 *            radix진법으로 표현된 표현식입니다.(접두어 제외 ex:0x, 0,...)
	 * @param radix
	 *            s의 표현식의 진법 (2에서 36사이의 값)
	 * @return 정수값
	 * @throws SMException
	 */
	public static long parse(String s, int radix) throws SMException
	{
		if (s == null) throw new SMException("argument s was Null");

		if (radix < MIN_RADIX || radix > MAX_RADIX) throw new SMException("radix value should be between 2 and 36");

		long result = 0;
		long mult = 1;
		int weight;

		s = s.toLowerCase();

		for (int i = s.length() - 1; i >= 0; i--)
		{
			weight = digits.indexOf(String.valueOf(s.charAt(i)));
			if (weight == -1) throw new SMException("Invalid number for the specified radix");

			result += (weight * mult);
			mult *= radix;
		}
		return result;
	}
}
